package com.ff.xyh.consumer.chatroom.config;

import com.ff.xyh.common.entity.message.RoomMessage;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalTime;

/**
 * @Auther FF
 * @Date 2022年 11月 30日
 * @Time 02:34
 */

@Configuration
public class RoomRabbitConfig {
    // 定义群聊交换机名
    public static final String EXCHANGE_DIRECT_CHAT = "chat.direct.ex1";
    public static final String QUEUE_SERVER_ROOM_1 = "server.room.q1";
    public static final String ROUTING_KEY_ROOM_1 = "RoomServer1";

    public static final String QUEUE_SERVER_USER_1 = "server.user.q1";
    public static final String ROUTING_KEY_USER_1 = "UserServer1";
//    public static final String ROUTING_KEY_USER_ONLINE2 = "userOnline2";

    public static final String QUEUE_SERVER_USER_LOCK_1 = "server.user.lock.q1";
    public static final String ROUTING_KEY_USER_LOCK_1 = "UserLockServer1";

    /** 创建直接交换机并绑定对列的 方法一 : 通过bean注解声明并绑定 然后在消费者监听队列即可 */
    /** 1
     * 声明房间 直接交换机
     * @return
     */
    @Bean
    public DirectExchange roomDirectExchange () { return new DirectExchange(EXCHANGE_DIRECT_CHAT); }

    /** 2
     * 声明 本服务器的监听的房间队列
     * @return
     */
    @Bean
    public Queue serverRoomQ1() { return new Queue(QUEUE_SERVER_ROOM_1); }

    /** 3
     * 根据路由绑定对列到交换机
     * @param serverRoomQ1
     * @param roomDirectExchange
     * @return
     */
    @Bean
    public Binding roomBinding(Queue serverRoomQ1, DirectExchange roomDirectExchange) {
        return BindingBuilder.bind(serverRoomQ1).to(roomDirectExchange).with(ROUTING_KEY_ROOM_1);
    }
    /** 创建用户队列， 用用户的routingKey绑定用户队列到交换机 */
    @Bean
    public Queue serverUserQ1() { return new Queue(QUEUE_SERVER_USER_1); }
    @Bean
    public Binding userBinding(Queue serverUserQ1, DirectExchange roomDirectExchange) {
        return BindingBuilder.bind(serverUserQ1).to(roomDirectExchange).with(ROUTING_KEY_USER_1);
    }


    /** 创建用户队列， 用用户的routingKey绑定用户队列到交换机 */
    @Bean
    public Queue serverUserLockQ1() { return new Queue(QUEUE_SERVER_USER_LOCK_1); }
    @Bean
    public Binding userLockBinding(Queue serverUserLockQ1, DirectExchange roomDirectExchange) {
        return BindingBuilder.bind(serverUserLockQ1).to(roomDirectExchange).with(ROUTING_KEY_USER_LOCK_1);
    }


//    /** 4
//     * 创建监听器 监听队列 到 监听类中声明
//     * @param roomMessage
//     */
//    @RabbitListener(queues = QUEUE_SERVER_USER_1)
//    public void userOnlineQueueConsumer1(RoomMessage roomMessage) {
//        System.out.println("userOnlineQueueConsumer1 listen user.q1 received the message: {" + roomMessage + "}, when " + LocalTime.now());
//    }


    /** 方法二： 直接在监听器上声明队列交换机并绑定 */
//    @RabbitListener(bindings = @QueueBinding(
//            value = @org.springframework.amqp.rabbit.annotation.Queue(name = QUEUE_USER_1),
//            exchange = @org.springframework.amqp.rabbit.annotation.Exchange(name = EXCHANGE_DIRECT_USER_1, type = ExchangeTypes.DIRECT),
//            key = {ROUTING_KEY_USER_ONLINE, ROUTING_KEY_USER_ONLINE2}
//    ))






    /**
     * 添加自定义消息转换器 不需要声明 会自动注入
     * 原有消息转换器为序列化对象，性能差
     * 注意： 发送方与接收方需要使用相同的转换器
     * @return
     */
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }


}